home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint96sb.zoo / src / intr.spp < prev    next >
Encoding:
Text File  |  1992-10-06  |  11.2 KB  |  429 lines

  1. %include "magic.i"
  2. ;
  3. ; interrupt wrapping routines; these should just save registers and call
  4. ; the appropriate C handlers, unless speed is a major problem
  5. ;
  6.     TEXT
  7. ;
  8. ; first, utilities for setting processor status level
  9. ;
  10.     XDEF    _spl7,_spl
  11. _spl7:
  12.     move.w    sr,d0
  13.     ori.w    #$0700,sr
  14.     rts
  15. _spl:
  16.     move.w    4(sp),d0
  17.     move.w    d0,sr
  18.     rts
  19.  
  20.     XDEF    _mint_5ms
  21.     XDEF    _mint_timer
  22.     XDEF    _mint_vbl
  23.     XREF    _timeout    ; C time routine
  24.     XREF    _old_timer    ; old GEMDOS time vector
  25.     XREF    _old_vbl    ; old GEMDOS vbl vector
  26.     XREF    _old_5ms
  27.     XREF    _build_context
  28.     XREF    _restore_context
  29.     XREF    _proc_clock        ; controls process' allocation of CPU time
  30.     XREF    _curproc
  31.     XREF    _enter_kernel
  32.     XREF    _leave_kernel
  33.     XREF    _preempt
  34.     XREF    _in_kernel
  35.  
  36. ; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
  37. _mint_5ms:
  38.     move.l    a0,-(sp)
  39.     move.l    _curproc,a0
  40.     tst.w    _in_kernel
  41.     bne.s    L_systime
  42.     lea    P_USRTIME(a0),a0    ; get offset to curproc->usrtime
  43.     addq.l    #5,(a0)            ; update the time
  44.     move.l    (sp)+,a0
  45.     move.l    _old_5ms+8,-(sp)    ; branch to old vector
  46.     rts
  47. L_systime:
  48.     lea    P_SYSTIME(a0),a0    ; get offset to curproc->systime
  49.     addq.l    #5,(a0)
  50.     move.l    (sp)+,a0
  51.     move.l    _old_5ms+8,-(sp)
  52.     rts
  53.  
  54. _mint_timer:
  55.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  56.     jsr    _timeout
  57.     movem.l    (sp)+,d0-d2/a0-a2
  58.     move.l    _old_timer+8,-(sp)    ; jump to GEMDOS time vector
  59.     rts
  60.  
  61. _mint_vbl:
  62.     tst.w    ($59e).w        ; test longframe (AKP)
  63.     beq.s    L_short1
  64.     clr.w    -(sp)            ; yes, long frames: push a frame word
  65. L_short1:
  66.     pea    L_comeback        ; push fake PC
  67.     move.w    sr,-(sp)        ; push status register
  68.     move.l    _old_vbl+8,-(sp)    ; go service the interrupt
  69.     rts
  70.  
  71. L_comeback:
  72.     tst.w    _proc_clock        ; has time expired yet?
  73.     beq.s    L_expired        ; yes -- maybe go switch processes
  74. L_out:
  75.     rte                ; no -- just return
  76.  
  77. L_expired:
  78.     btst    #5,(sp)            ; user mode?
  79.     bne.s    L_out            ; no -- switching is not possible
  80.     tst.w    ($43e).w        ; test floppy disk lock variable
  81.     bne.s    L_out            ; if locked, can't switch
  82.     tst.w    _in_kernel        ; are we doing a kernel operation?
  83.     bne.s    L_out
  84. L_switch:
  85.     clr.w    -(sp)            ; no frame format needed
  86.     move.l    _curproc,-(sp)
  87.     addq.l    #4,(sp)            ; to get &curproc->ctxt[SYSCALL]
  88.     jsr    _build_context        ; build context
  89.     move.l    _curproc,a0
  90.     move.l    (a0),sp            ; use curproc->sysstack
  91.     jsr    _enter_kernel        ; enter kernel
  92.     jsr    _preempt        ; yield processor
  93.     ori.w    #$700,sr        ; spl7()
  94.     jsr    _leave_kernel        ; restore vectors
  95.     move.l    _curproc,a0
  96.     pea    4(a0)
  97.     jsr    _restore_context    ; back to user
  98.  
  99. ;
  100. ; reset routine -- called on a warm boot. Note that TOS sends the
  101. ; address to which we should return in register a6. Also note that
  102. ; the stack pointer is in an unknown state, so we set up our own
  103. ;
  104.     XDEF    _reset
  105.     XREF    _tmpstack        ; see main.c
  106.     XREF    _restr_intr
  107.  
  108. _reset:
  109.     move.w    #$2700,sr        ; avoid interruption here
  110.     move.l    sp,_tmpstack        ; save A7
  111.     lea    _tmpstack,sp        ; set up temporary stack
  112.     lea    256(sp),sp
  113.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  114.     jsr    _restr_intr        ; restore interrupts
  115.     movem.l    (sp)+,d0-d2/a0-a2    ; restore registers
  116.     move.l    _tmpstack,sp
  117.     jmp    (a6)            ; reset again
  118.  
  119. ;
  120. ; routine for doing a reboot
  121. ;
  122.     XDEF    _reboot
  123. _reboot:
  124.     move.w    #$2700,sr        ; avoid interrupts
  125.     move.l    (0).w,sp        ; get sp after reboot
  126.     move.l    (4).w,a6        ; get new reboot address
  127.     jmp    _reset
  128.  
  129. ;
  130. ; routine for mouse packet handling
  131. ;
  132.     XDEF    _newmvec
  133.     XDEF    _newjvec
  134.     XREF    _mouse_handler
  135. ; Experimental three button mouse support (by jr@ms.maus.de,
  136. ; August 4, 1992
  137. ;
  138. ; Should work with the mice shipped with Atari's ASV or
  139. ; compatible ones (like Golden Image GI-6000). Might not work
  140. ; on ST/STE systems with older IKBD's or keyboards. The middle mouse
  141. ; button is wired to one of the joystick directions on joystick one.
  142. ;
  143. ; _newmvec is the same as before with two exceptions:
  144. ; 1. the first byte of the packet is saved for the joystick handler
  145. ; 2. the bit for the middle mouse button is ored in
  146. ;
  147. ; _newjvec hooks into the joystick vector and chains to the normal
  148. ; handler. The middle mouse button state is saved in a special
  149. ; register for _newmvec, and a 'fake' mouse packet is set up
  150. ; (by merging the last mouse packet header, or-ing in the
  151. ; middle button state and using 0/0 for the x/y increment).
  152. ;
  153. ; the faked_packet and third_button variables are declared at the
  154. ; end of this file
  155.  
  156. _newmvec:
  157.     move.l    a0,-(sp)
  158.     move.b    (a0),d0
  159.     move.b    d0,faked_packet
  160.     or.b    third_button,d0
  161.     move.b    d0,(a0)
  162.     jsr    _mouse_handler
  163.     move.l    (sp)+,a0
  164.     rts
  165. ;
  166. ; routine for joystick packet handling (used for three button mice)
  167. ;
  168.     XDEF    _newjvec
  169.     XREF    _oldjvec
  170.  
  171. _newjvec:
  172.     move.l    a0,-(sp)    ; save a0 on the stack
  173.     move.b    2(a0),d0    ; joystick direction
  174.     and.b    #1,d0        ; middle mouse button in lowest bit
  175.     add.b    d0,d0        ; times 4
  176.     add.b    d0,d0
  177.     move.b    d0,third_button    ; save it for use in newmvec
  178.  
  179.     lea    faked_packet,a0    ; 'our' faked mouse event
  180.     move.b    (a0),d0
  181.     and.b    #$3,d0        ; unmask our mouse button
  182.     or.b    #$F8,d0        ; or in correct header
  183.     or.b    third_button,d0    ; or in the current status
  184.     move.b    d0,(a0)        ; write it back
  185.  
  186.     move.l    a0,-(sp)    ; pass pointer to fake packet
  187.     jsr    _mouse_handler    ; to \dev\mouse handler
  188.     addq.l    #4,sp        ; pop parameter
  189.     move.l    (sp)+,a0    ; restore original a0 value
  190.     move.l    _oldjvec,-(sp)    ; jump to original joystick handler
  191.     rts
  192. ;
  193. ; new ikbd keyboard interrupt vector
  194. ; kintr is a global variable that should be non-zero if a keyboard
  195. ; event occured
  196. ;
  197.     XDEF    _new_ikbd
  198.     XREF    _old_ikbd
  199.     XREF    _kintr
  200.  
  201. _new_ikbd:
  202.     move.w    #1,_kintr
  203.     move.l    _old_ikbd+8,-(sp)
  204.     rts            ; jump to system interrupt routine
  205.  
  206. ;
  207. ; simple signal handlers
  208. ; global variables referenced:
  209. ; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
  210. ; sig_routine: (signal.c): pointer to which signal catching routine to
  211. ;          call (e.g. for SIGBUS, or whatever)
  212. ;
  213.     XDEF    _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv,_new_linef
  214.     XDEF    _new_trace,_new_chk,_new_trapv,_new_fpcp,_new_mmu,_new_pmmuacc
  215.     XDEF    _new_uninit,_new_spurious,_new_format,_new_cpv
  216.     XREF    _in_kernel,_sig_routine
  217.     XREF    _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
  218.     XREF    _haltformat,_haltcpv
  219.     XREF    _sig_exc
  220.     
  221. _new_bus:
  222.     move.w    #$8,_sig_exc
  223.     move.l    #_sigbus,_sig_routine
  224. Do_sig:
  225.     tst.w    _in_kernel        ; are we already in the kernel?
  226.     bne.s    Kernel            ; yes
  227.     move.w    _sig_exc,-(sp)
  228.     move.l    _curproc,-(sp)
  229.     addq.l    #4,(sp)            ; push offset of save area
  230.     jsr    _build_context
  231.     move.l    _curproc,a4
  232.     move.l    (a4),sp            ; put us in the system stack
  233.     jsr    _enter_kernel        ; set up kernel vectors
  234.     move.l    _sig_routine,a1        ; get signal handling routine
  235.     jsr    (a1)            ; go do it
  236.     ori.w    #$0700,sr        ; spl7()
  237.     jsr    _leave_kernel        ; leave kernel
  238.     addq.w    #4,a4            ; get context save area address
  239.     move.l    a4,-(sp)        ; push it
  240.     jsr    _restore_context    ; restore the context
  241. ;
  242. ; here's what we do if we already were in the kernel
  243. ;
  244. Kernel:
  245.     movem.l    d0-d2/a0-a2,-(sp)    ; save reggies
  246.     move.l    _sig_routine,a1        ; get handler
  247.     jsr    (a1)            ; go do it
  248.     movem.l    (sp)+,d0-d2/a0-a2
  249.     rte
  250. _new_addr:
  251.     move.w    #$c,_sig_exc
  252.     move.l    #_sigaddr,_sig_routine
  253.     bra.s    Do_sig
  254. _new_ill:
  255.     move.w    #$10,_sig_exc
  256.     move.l    #_sigill,_sig_routine
  257.     bra.s    Do_sig            ; ASM pre-5.52.3 barfs on this :-(
  258. _new_divzero:
  259.     move.w    #$14,_sig_exc
  260.     move.l    #_sigfpe,_sig_routine
  261.     bra    Do_sig
  262. _new_linef:
  263.     move.w    #$2c,_sig_exc
  264.     move.l    #_sigill,_sig_routine
  265.     bra    Do_sig
  266. _new_chk:
  267.     move.w    #$18,_sig_exc
  268.     move.l    #_sigfpe,_sig_routine
  269.     bra    Do_sig
  270. _new_trapv:
  271.     move.w    #$1c,_sig_exc
  272.     move.l    #_sigfpe,_sig_routine
  273.     bra    Do_sig
  274. _new_fpcp:
  275. ; don't set _sig_exc - only needed for 68000 vectors
  276.     move.l    #_sigfpe,_sig_routine
  277.     bra    Do_sig
  278. _new_mmu:
  279. ; don't set _sig_exc - only needed for 68000 vectors
  280.     move.l    #_sigill,_sig_routine
  281.     bra    Do_sig
  282. _new_pmmuacc:
  283. ; don't set _sig_exc - only needed for 68000 vectors
  284.     move.l    #_sigbus,_sig_routine
  285.     bra    Do_sig
  286. _new_uninit:
  287.     move.w    #$3c,_sig_exc
  288.     move.l    #_sigbus,_sig_routine
  289.     bra    Do_sig
  290. _new_spurious:
  291.     move.w    #$60,_sig_exc
  292.     move.l    #_sigbus,_sig_routine
  293.     bra    Do_sig
  294. _new_format:
  295.     move.l    #_haltformat,_sig_routine
  296.     bra    Do_sig
  297. _new_cpv:
  298.     move.l    #_haltcpv,_sig_routine
  299.     bra    Do_sig
  300.  
  301.     XREF    _old_priv        ; old privilege violation vector
  302. _new_priv:
  303.     move.w    #$20,_sig_exc
  304.     move.l    #_sigpriv,_sig_routine
  305.     tst.w    ($59e).w        ; 68000s always get SIGPRIV
  306.     beq    Do_sig
  307.     movem.l    d0/a0,-(a7)
  308.     move.l    10(a7),a0        ; fetch exception address
  309.     move.w    (a0),d0
  310.     and.w    #$ffc0,d0        ; partially decode move sr,...
  311.     cmp.w    #$40c0,d0        ; and test it
  312.     movem.l    (a7)+,d0/a0        ; preserves the flags
  313.     bne    Do_sig            ; doesn't look like sr,...
  314.     move.l    _old_priv+8,-(sp)    ; let our parent handle it
  315.     rts
  316.  
  317. ; XBRA vectors from main.c
  318.     XREF    _old_dos,_old_bios,_old_xbios
  319.     XREF    _old_divzero,_old_chk,_old_trapv
  320.  
  321. _new_trace:
  322.     btst    #5,(a7)            ; only check when called from supervisor mode
  323.     beq.s    S_1
  324.     cmp.l    #_old_dos+12,2(a7)    ; lets not trace the kernel !
  325.     beq.s    S_2
  326.     cmp.l    #_old_xbios+12,2(a7)
  327.     beq.s    S_2
  328.     cmp.l    #_old_bios+12,2(a7)
  329.     beq.s    S_2
  330.     cmp.l    #_old_divzero+12,2(a7)
  331.     beq.s    S_2
  332.     cmp.l    #_old_trapv+12,2(a7)
  333.     beq.s    S_2
  334.     cmp.l    #_old_chk+12,2(a7)
  335.     beq.s    S_2
  336. ; add any other non-traceable entities here...
  337.  
  338. S_1:    move.w    #$24,_sig_exc
  339.     move.l    #_sigtrap,_sig_routine
  340.     bra    Do_sig
  341.  
  342. S_2:    and.w    #$3fff,(a7)        ; clear both trace bits
  343.     rte                ; and re-start the handler
  344.  
  345. ;
  346. ; BIOS disk vectors for pseudo-disks like U: and X:; these are present
  347. ; just in case some program (foolishly) attempts to access these drives
  348. ; directly and gets horribly confused
  349. ;
  350.     XREF    _old_getbpb    ; old Getbpb vector
  351.     XREF    _old_mediach    ; old Mediach vector
  352.     XREF    _old_rwabs    ; old Rwabs vector
  353.     XREF    _aliasdrv    ; array of drive aliases
  354.     XDEF    _new_getbpb
  355.     XDEF    _new_mediach
  356.     XDEF    _new_rwabs
  357.  
  358. _new_getbpb:
  359.     move.w    4(sp),d0    ; check the drive
  360.     move.w    d0,d1        ; get index
  361.     add.w    d0,d1        ; convert to index
  362.     lea    _aliasdrv,a0
  363.     move.w    0(a0,d1.w),d1    ; alias drive?
  364.     beq.s    noalias0
  365.     move.w    d1,d0
  366.     subq.w    #1,d0        ; adjust for aliasdrv base of '@'
  367. noalias0:
  368.     cmp.w    #$1f,d0        ; is this a legal drive?
  369.     bhi.s    nobpb        ; no -- ignore it
  370.     cmp.w    #$14,d0        ; drive U:?
  371.     beq.s    nobpb        ; yes, no BPB available
  372.     move.l    _old_getbpb+8,a0    ; not our drive
  373.     jmp    (a0)        ; call the old vector for it
  374. nobpb:
  375.     moveq.l    #0,d0        ; 0 means "no BPB read"
  376.     rts
  377.  
  378. _new_mediach:
  379.     move.w    4(sp),d0    ; check the drive
  380.     move.w    d0,d1        ; get index
  381.     add.w    d0,d1        ; convert to index
  382.     lea    _aliasdrv,a0
  383.     move.w    0(a0,d1.w),d1    ; alias drive?
  384.     beq.s    noalias1
  385.     move.w    d1,d0
  386.     subq.w    #1,d0        ; adjust for aliasdrv base
  387. noalias1:
  388.     cmp.w    #$1f,d0        ; legal drive?
  389.     bhi.s    nobpb        ; no -- ignore it
  390.     cmp.w    #$14,d0        ; drive U:?
  391.     beq.s    nochng        ; yes, no change
  392.     move.l    _old_mediach+8,a0    ; not our drive
  393.     jmp    (a0)        ; call the old vector for it
  394. nochng:
  395.     moveq.l    #0,d0        ; 0 means "definitely no change"
  396.     rts
  397.  
  398. _new_rwabs:
  399.     move.w    $e(sp),d0    ; check the drive
  400.     move.w    d0,d1        ; get index
  401.     add.w    d0,d1        ; convert to index
  402.     lea    _aliasdrv,a0
  403.     move.w    0(a0,d1.w),d1    ; alias drive?
  404.     beq.s    noalias2
  405.     move.w    d1,d0
  406.     subq.w    #1,d0        ; adjust for aliasdrv base
  407. noalias2:
  408.     cmp.w    #$1f,d0        ; legal drive?
  409.     bhi.s    nobpb        ; no -- ignore it
  410.     cmp.w    #$14,d0        ; drive U:?
  411.     beq.s    rwdone        ; yes, fake it
  412.     move.l    _old_rwabs+8,a0    ; not our drive
  413.     jmp    (a0)        ; call the old vector for it
  414. rwdone:
  415.     moveq.l    #0,d0        ; 0 means "successful operation"
  416.     rts
  417.  
  418.     DATA
  419. ; buffer for faked mouse packet (actually only 3 bytes)
  420.  
  421. faked_packet:
  422.     dc.l    0
  423.  
  424. ; here we store the additional button state
  425. third_button:
  426.     dc.w    0
  427.  
  428.     END
  429.